package com.liveinstars.gateway.application.config;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Charsets;
import com.liveinstars.gateway.business.service.DynamicRouteService;
import io.micrometer.core.instrument.util.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.PostConstruct;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.util.*;

/**
 * @author: ting
 * @date: 2019-07-16
 */
@Component
public class DynamicRouteConfigByRedis {

    private final static Logger logger = LoggerFactory.getLogger(DynamicRouteConfigByRedis.class);

    @Autowired
    private DynamicRouteService dynamicRouteService;


    @PostConstruct
    public void dynamicRouteByApolloListener() {
        try {
//            List<RouteDefinition> definitionListF = new ArrayList<>();
//            definitionListF.add(getRouteDefi("activity", "/activity/**", "http://localhost:8012", "AesAuth", 1 ));
//            definitionListF.add(getRouteDefi("account", "/account/**", "http://localhost:8014", "AesAuth", 2 ));
//            definitionListF.add(getRouteDefi("tobaidu", "/tobaidu/**", "http://www.baidu.com", "AesAuth", 3 ));
//            definitionListF.add(getRouteDefi("jd", "/jd", "http://www.baidu.com", "", 4 ));
            List<RouteDefinition> definitionListF= JSON.parseArray(getFromJSONFile(), RouteDefinition.class);
            logger.info("dynamicRouteByApolloListener {}", definitionListF.size());
//            String configInfoF = cacheService.get("dynamic.route.info");
//            List<RouteDefinition> definitionListF= JSON.parseArray(configInfoF, RouteDefinition.class);
            dynamicRouteService.updateAll(definitionListF);
        } catch (Exception e) {
            logger.error("dynamicRouteByApolloListener", e);
        }
    }

    public String getFromJSONFile() {
        String arry = null;
        try {
            Resource resource = new ClassPathResource("route_config.json");
            arry = (IOUtils.toString(
                    resource.getInputStream()));

        } catch (IOException e) {
            e.printStackTrace();
            logger.error("getjsonfromfile", e);
        }
        logger.info("getjson {}", arry);
        return arry;
    }

    private RouteDefinition getRouteDefi(String id, String pattern, String url, String filter, int order) {
        RouteDefinition routeDefinition = new RouteDefinition();
//        Map<String, String> filterParams = new HashMap<>(8);
        URI uri = UriComponentsBuilder.fromUriString(url).build().toUri();

        routeDefinition.setId(id);

//// 每秒最大访问次数
//        filterParams.put("redis-rate-limiter.replenishRate", "2");
//// 令牌桶最大容量
//        filterParams.put("redis-rate-limiter.burstCapacity", "3");
//// 限流策略(#{@BeanName})
//        filterParams.put("key-resolver", "#{@hostAddressKeyResolver}");
//// 自定义限流器(#{@BeanName})
////filterParams.put("rate-limiter", "#{@redisRateLimiter}");
//        filterDefinition.setArgs(filterParams);
        PredicateDefinition predicateDefinition = new PredicateDefinition();
        predicateDefinition.setName("Path");
        Map<String, String> predicateParams = new HashMap<>(8);
        predicateParams.put("_genkey_0", pattern);
        predicateDefinition.setArgs(predicateParams);

        routeDefinition.setPredicates(Arrays.asList(predicateDefinition));
        if(!StringUtils.isEmpty(filter)){
            FilterDefinition filterDefinition = new FilterDefinition();
            filterDefinition.setName(filter);
            routeDefinition.setFilters(Arrays.asList(filterDefinition));
        }
        routeDefinition.setUri(uri);
        routeDefinition.setOrder(order);
        return routeDefinition;
    }


}
